<?php
// +----------------------------------------------------------------------
// | QSCMS
// +----------------------------------------------------------------------
// | Copyright (c)  2025 https://www.qqss.net All rights reserved.
// +----------------------------------------------------------------------
// | Licensed QSCMS is not free software, commercial use must purchase official license from official website to avoid unnecessary legal disputes.
// +----------------------------------------------------------------------
// | Author: Contract 990504246@qq.com
// +----------------------------------------------------------------------

namespace app\common\model;

use think\Model;
use app\common\util\PinyinHelper;

class GoodsCategory extends Model
{
  protected $autoWriteTimestamp = true;

  // Get the goods in the category
  public function goods()
  {
    return $this->hasMany('Goods', 'cate_id');
  }

  // Get the name of the category
  public function searchNameAttr($query, $value, $data)
  {
    $query->where('name', 'like', '%' . $value . '%');
  }

  // Get the status of the category
  public function searchStatusAttr($query, $value, $data)
  {
    if ($value != '') {
      $query->where('status', $value);
    }
  }

  // Get the navigation menu categories
  public function searchIsMenuAttr($query, $value, $data)
  {
    if ($value !== '') {
      $query->where('is_menu', $value);
    }
  }

  // Get the number of goods in the category
  public function getCountAttr()
  {
    $goods = $this->goods()->select();
    $i     = 0;
    foreach (collect($goods) as $good) {
      if ($good->status == 0) {
        continue;
      }
      $i++;
    }
    return $i;
  }

  /**
   * Associate with specifications
   */
  public function spec()
  {
    return $this->belongsTo('GoodsSpec', 'spec_id');
  }

  /**
   * Get the specification information of the category
   */
  public function getSpecInfoAttr()
  {
    if (!$this->spec_id) {
      return null;
    }

    $spec = GoodsSpec::find($this->spec_id);
    return $spec ? $spec : null;
  }

  // Get the URL of the category
  public function getUrlAttr()
  {
    return _url_('goods.category', ['pinyin' => $this->pinyin]);
  }

  /**
   * Get all navigation menu categories
   * @return \think\Collection
   */
  public static function getMenuCategories()
  {
    return self::where('status', 1)
      ->where('is_menu', 1)
      ->order('sort desc, id asc')
      ->select();
  }

  /**
   * Model event - Automatically generate pinyin after saving
   */
  public static function onAfterInsert($category)
  {
    // Use the original data of the model
    $data = $category->toArray();

    // If the pinyin is empty, generate pinyin 
    if (empty($data['pinyin']) && !empty($data['name'])) {
      $pinyin = match (true) {
        is_numeric($data['name']) => 'fenlei' . $data['name'],
        default => PinyinHelper::generateUniquePinyin($data['name'], 'goods_category', $data['id'])
      };

      // Directly update the database to avoid triggering the event loop
      self::where('id', $data['id'])->update(['pinyin' => $pinyin]);
    }
  }

  /**
   * Model event - Automatically update pinyin after updating
   */
  public static function onAfterUpdate($category)
  {
    // Use the original data of the model
    $data   = $category->toArray();
    $origin = $category->getOrigin();

    // If the name changes or the pinyin is empty, update the pinyin
    if ((isset($origin['name']) && $data['name'] != $origin['name']) || empty($data['pinyin'])) {
      if (!empty($data['name'])) {
        $pinyin = match (true) {
          is_numeric($data['name']) => 'fenlei' . $data['name'],
          default => PinyinHelper::generateUniquePinyin($data['name'], 'goods_category', $data['id'])
        };

        // Directly update the database to avoid triggering the event loop
        self::where('id', $data['id'])->update(['pinyin' => $pinyin]);
      }
    }
  }

  public static function getCategoryList()
  {
    $res = self::where([
      'status'  => 1,
      'pid'     => 0,
      'is_menu' => 1
    ])->order('sort desc, id desc')->field('id,name,pic,is_spec_filter')->select();

    $list = [];
    foreach ($res as $item) {
      $item->goods_count = $item->goods()->where([
        'status' => 1,
      ])->count();
      $item->children    = self::getCategoryChildren($item->id);
      $list[]            = $item;
    }

    return $list;
  }

  private static function getCategoryChildren($parentId)
  {
    $children = self::where([
      'status' => 1,
      'pid'    => $parentId
    ])->field('id,name,pic,is_spec_filter')->order('sort desc, id desc')->select()->each(function ($child) {
      $child->goods_count = $child->goods()->where([
        'status' => 1,
      ])->count();
      $child->children = self::getCategoryChildren($child->id); // 递归获取下级分类
    });
    return $children;
  }
}
